//
//  NSDate+convenience.m
//  Calendar-Demo
//
//  Created by unbank on 15-7-13.
//  Copyright (c) 2015年 ***. All rights reserved.
//

#import "NSDate+convenience.h"

@implementation NSDate (convenience)

- (NSInteger)year
{
    NSCalendar *gregorian = [[NSCalendar alloc]
                             initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    NSDateComponents *components = [gregorian components:NSCalendarUnitYear fromDate:self];
    return [components year];
}

- (NSDate *)setYear:(NSInteger)year
{
    NSDateComponents *comp = [[NSDateComponents alloc] init];

    [comp setMonth:self.month];

    [comp setDay:self.day];

    [comp setYear:year];

    NSCalendar *myCal = [[NSCalendar alloc]initWithCalendarIdentifier:NSCalendarIdentifierGregorian];

    NSDate *destinationDate = [myCal dateFromComponents:comp];

    return destinationDate;
}
- (NSInteger)month
{
    NSCalendar *gregorian = [[NSCalendar alloc]
                             initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    NSDateComponents *components = [gregorian components:NSCalendarUnitMonth fromDate:self];
    return [components month];
}

- (NSDate *)setMonth:(NSInteger)month
{
    NSDateComponents *comp = [[NSDateComponents alloc] init];

    [comp setMonth:month];

    [comp setDay:self.day];

    [comp setYear:self.year];

    NSCalendar *myCal = [[NSCalendar alloc]initWithCalendarIdentifier:NSCalendarIdentifierGregorian];

    NSDate *destinationDate = [myCal dateFromComponents:comp];

    return destinationDate;
}

- (NSInteger)day
{
    NSCalendar *gregorian = [[NSCalendar alloc]
                             initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    NSDateComponents *components = [gregorian components:NSCalendarUnitDay fromDate:self];
    return [components day];
}

- (NSDate *)setDay:(NSInteger)day
{
    NSDateComponents *comp = [[NSDateComponents alloc] init];

    [comp setMonth:self.month];

    [comp setDay:day];

    [comp setYear:self.year];

    NSCalendar *myCal = [[NSCalendar alloc]initWithCalendarIdentifier:NSCalendarIdentifierGregorian];

    NSDate *destinationDate = [myCal dateFromComponents:comp];

    return destinationDate;
}

- (NSInteger)firstWeekDayInMonth
{
    NSCalendar *gregorian = [[NSCalendar alloc]
                             initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    [gregorian setFirstWeekday:2]; //monday is first day

    //Set date to first of month
    NSDateComponents *comps = [gregorian components:NSCalendarUnitYear | NSCalendarUnitMonth |  NSCalendarUnitDay fromDate:self];
    [comps setDay:1];
    NSDate *newDate = [gregorian dateFromComponents:comps];

    return [gregorian ordinalityOfUnit:NSCalendarUnitWeekday inUnit:NSCalendarUnitWeekOfMonth forDate:newDate];
}

- (NSDate *)offsetMonth:(int)numMonths
{
    NSCalendar *gregorian = [[NSCalendar alloc]
                             initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    [gregorian setFirstWeekday:2]; //monday is first day

    NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
    [offsetComponents setMonth:numMonths];
    //[offsetComponents setHour:1];
    //[offsetComponents setMinute:30];
    return [gregorian dateByAddingComponents:offsetComponents
                                      toDate:self options:0];
}

- (NSDate *)offsetHours:(int)hours
{
    NSCalendar *gregorian = [[NSCalendar alloc]
                             initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    [gregorian setFirstWeekday:2]; //monday is first day

    NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
    //[offsetComponents setMonth:numMonths];
    [offsetComponents setHour:hours];
    //[offsetComponents setMinute:30];
    return [gregorian dateByAddingComponents:offsetComponents
                                      toDate:self options:0];
}

-(NSDate *)offsetDay:(int)numDays
{
    NSCalendar *gregorian = [[NSCalendar alloc]
                             initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    [gregorian setFirstWeekday:2]; //monday is first day

    NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
    [offsetComponents setDay:numDays];
    //[offsetComponents setHour:1];
    //[offsetComponents setMinute:30];

    return [gregorian dateByAddingComponents:offsetComponents
                                      toDate:self options:0];
}



- (NSInteger)numDaysInMonth
{
    NSCalendar *cal = [NSCalendar currentCalendar];
    NSRange rng = [cal rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:self];
    NSUInteger numberOfDaysInMonth = rng.length;
    return numberOfDaysInMonth;
}

+ (NSDate *)dateStartOfDay:(NSDate *)date
{
    NSCalendar *gregorian = [[NSCalendar alloc]
                             initWithCalendarIdentifier:NSCalendarIdentifierGregorian];

    NSDateComponents *components =
    [gregorian components:(NSCalendarUnitYear | NSCalendarUnitMonth |
                           NSCalendarUnitDay) fromDate: date];
    return [gregorian dateFromComponents:components];
}

+ (NSDate *)dateStartOfWeek
{
    NSCalendar *gregorian = [[NSCalendar alloc]
                             initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    [gregorian setFirstWeekday:2]; //monday is first day

    NSDateComponents *components = [[NSCalendar currentCalendar] components:NSCalendarUnitWeekday fromDate:[NSDate date]];

    NSDateComponents *componentsToSubtract = [[NSDateComponents alloc] init];
    [componentsToSubtract setDay: - ((([components weekday] - [gregorian firstWeekday])
                                      + 7 ) % 7)];
    NSDate *beginningOfWeek = [gregorian dateByAddingComponents:componentsToSubtract toDate:[NSDate date] options:0];

    NSDateComponents *componentsStripped = [gregorian components: (NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay)
                                                        fromDate: beginningOfWeek];

    //gestript
    beginningOfWeek = [gregorian dateFromComponents: componentsStripped];

    return beginningOfWeek;
}

+ (NSDate *)dateEndOfWeek
{
    NSCalendar *gregorian =[[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];

    NSDateComponents *components = [[NSCalendar currentCalendar] components:NSCalendarUnitWeekday fromDate:[NSDate date]];


    NSDateComponents *componentsToAdd = [[NSDateComponents alloc] init];
    [componentsToAdd setDay: + (((([components weekday] - [gregorian firstWeekday])
                                  + 7 ) % 7))+6];
    NSDate *endOfWeek = [gregorian dateByAddingComponents:componentsToAdd toDate:[NSDate date] options:0];

    NSDateComponents *componentsStripped = [gregorian components: (NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay)
                                                        fromDate: endOfWeek];

    //gestript
    endOfWeek = [gregorian dateFromComponents: componentsStripped];
    return endOfWeek;
}

- (ComparisonResult )compareToDay:(NSDate *)date
{
    ComparisonResult result = ComparisonResultBefore;

    if ([date year] > [self year])
    {
        result = ComparisonResultBefore;
    }
    else if ([date year] == [self year])
    {
        if ([date month] > [self month])
        {
            result = ComparisonResultBefore;
        }
        else if ([date month] == [self month])
        {
            if ([date day] > [self day])
            {
                result = ComparisonResultBefore;
            }
            else if ([date day] == [self day])
            {
                result = ComparisonResultSame;
            }
            else
            {
                result = ComparisonResultLater;
            }
        }
        else
        {
            result = ComparisonResultLater;
        }
    }
    else
    {
        result = ComparisonResultLater;
    }
    return result;
}

- (ComparisonResult )compareToMonth:(NSDate *)date
{
    ComparisonResult result = ComparisonResultBefore;

    if ([date year] > [self year])
    {
        result = ComparisonResultBefore;
    }
    else if ([date year] == [self year])
    {
        if ([date month] > [self month])
        {
            result = ComparisonResultBefore;
        }
        else if ([date month] == [self month])
        {
            result = ComparisonResultSame;
        }
        else
        {
            result = ComparisonResultLater;
        }
    }
    else
    {
        result = ComparisonResultLater;
    }
    return result;

}

- (ComparisonResult )compareToYear:(NSDate *)date
{
    ComparisonResult result = ComparisonResultBefore;

    if ([date year] > [self year])
    {
        result = ComparisonResultBefore;
    }
    else if ([date year] == [self year])
    {
        result = ComparisonResultSame;
    }
    else
    {
        result = ComparisonResultLater;
    }
    return result;

}

- (NSDate *)getLocalDateFromAnyDate:(NSDate *)anyDate
{
    //设置源日期时区
    NSTimeZone* sourceTimeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"];
    //设置转换后的目标日期时区
    NSTimeZone* destinationTimeZone = [NSTimeZone localTimeZone];
    //得到源日期与世界标准时间的偏移量
    NSInteger sourceGMTOffset = [sourceTimeZone secondsFromGMTForDate:anyDate];
    //目标日期与本地时区的偏移量
    NSInteger destinationGMTOffset = [destinationTimeZone secondsFromGMTForDate:anyDate];
    //得到时间偏移量的差值
    NSTimeInterval interval = destinationGMTOffset - sourceGMTOffset;
    //转为现在时间
    NSDate* destinationDateNow = [[NSDate alloc] initWithTimeInterval:interval sinceDate:anyDate];
    
    return destinationDateNow;
}

+ (NSDate*)getNowTime{
    
    NSDate *curDate = [NSDate date];
    NSTimeInterval  timeZoneOffset=[[NSTimeZone systemTimeZone] secondsFromGMT];
    NSDate *currentDate=[curDate dateByAddingTimeInterval:timeZoneOffset];
    
    return currentDate;
}

// 比较两个日期之间间隔多少天
+ (NSInteger)daysBetweenDate:(NSDate*)fromDateTime andDate:(NSDate*)toDateTime
{
    NSDate *fromDate;
    NSDate *toDate;
    
    NSCalendar *calendar = [NSCalendar currentCalendar];
    
    [calendar rangeOfUnit:NSCalendarUnitDay startDate:&fromDate
                 interval:NULL forDate:fromDateTime];
    [calendar rangeOfUnit:NSCalendarUnitDay startDate:&toDate
                 interval:NULL forDate:toDateTime];
    
    NSDateComponents *difference = [calendar components:NSCalendarUnitDay
                                               fromDate:fromDate toDate:toDate options:0];
    
    return [difference day];
}

- (NSString *)separatorStyleDateTimeString{
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy-MM-dd"];
    NSString *dateString = [formatter stringFromDate:self];
    return dateString;
}

- (NSString *)separatorStyleDateTimeStringToMinAndSec{
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    NSString *dateString = [formatter stringFromDate:self];
    return dateString;
}

@end
